package cn.magicman.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;


/*
    验证 每个请求的HttpServletRequest对象 和 线程 都是独立的吗？
    对比对象内存地址与线程 ID
 */
@RestController
@RequestMapping("/request")
public class RequestValidationController {

    // 记录上一个请求的 request 对象地址和线程 ID
    private volatile String lastRequestHash;
    private volatile long lastThreadId;

    @GetMapping("/validate")
    public String validateRequest(HttpServletRequest request) {
        // 获取当前 request 对象的唯一标识（内存地址 + 哈希码）
        String currentRequestHash = System.identityHashCode(request) + "@" + request.hashCode();
        long currentThreadId = Thread.currentThread().getId();

        // 对比结果
        StringBuilder result = new StringBuilder();
        result.append("当前请求对象: ").append(currentRequestHash).append("\n");
        result.append("-------当前线程 ID: ").append(currentThreadId).append("\n");

        if (lastRequestHash != null) {
            result.append("-----上一个请求对象: ").append(lastRequestHash);  // 自动适配操作系统换行符
            result.append("-----上一个线程 ID: ").append(lastThreadId);
            result.append("-----对象是否相同: ")
                    .append(currentRequestHash.equals(lastRequestHash) ? "是" : "否");
            result.append("-----线程是否相同: ")
                    .append(currentThreadId == lastThreadId ? "是" : "否");
        }

        // 更新记录
        lastRequestHash = currentRequestHash;
        lastThreadId = currentThreadId;

        return result.toString();
    }

    @GetMapping("/advanced-request-validation")
    public String advancedValidation(HttpServletRequest request) {
        // 1. 外观对象的 identity hash
        int facadeHash = System.identityHashCode(request);

        // 2. 尝试获取真实对象 (Tomcat 特定)
        String realObjectHash = "unknown";
        try {
            java.lang.reflect.Field requestField = request.getClass().getDeclaredField("request");
            requestField.setAccessible(true);
            Object realRequest = requestField.get(request);
            realObjectHash = String.valueOf(System.identityHashCode(realRequest));
        } catch (Exception e) {
            realObjectHash = "reflection failed: " + e.getMessage();
        }

        return String.format("== 外观对象 (RequestFacade) ==%n" +
                        "身份哈希码: %d (每次请求相同)%n%n" +
                        "== 真实请求对象 ==%n" +
                        "身份哈希码: %s (应每次不同)%n%n" +
                        "线程: %s%n" +
                        "提示：真实对象哈希码应随请求变化，外观对象哈希码固定",
                facadeHash, realObjectHash, Thread.currentThread().getName());
    }
}